package pers.chao.tool.infrastructure.resource;

import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.io.resource.UrlResource;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Properties;

/**
 * Description: 资源相关的文件操作
 *
 * @author W.Chao
 * @date 2020/11/15 0:28
 **/
public final class ResUtil {
	private static final Logger logger = LoggerFactory.getLogger(ResUtil.class);

	private ResUtil() {
	}

	/**
	 * 从classpath获取Properties
	 *
	 * @param path
	 * @return
	 */
	public static Properties getProperties(String path) {
		ClassPathResource resource = new ClassPathResource(path);
		Properties properties = new Properties();
		try {
			properties.load(resource.getStream());
		} catch (IOException e) {
			logger.warn("Class path load properties occur error: {}", e.getMessage());
		}
		return properties;
	}

	public static String getStr(String path) {
		return ResourceUtil.readUtf8Str(path);
	}

	public static byte[] getByteArray(String path) {
		return ResourceUtil.readBytes(path);
	}

	public static InputStream getInputStream(String path) {
		return ResourceUtil.getStream(path);
	}

	public static BufferedReader getBufferedReader(String path) {
		return ResourceUtil.getUtf8Reader(path);
	}

	public static String getURLStr(URL url) {
		UrlResource urlResource = new UrlResource(url);
		return urlResource.readUtf8Str();
	}

	public static byte[] getURLByteArray(URL url) {
		UrlResource urlResource = new UrlResource(url);
		return urlResource.readBytes();
	}

	public static BufferedReader getURLBufferedReader(URL url) {
		UrlResource urlResource = new UrlResource(url);
		return urlResource.getReader(StandardCharsets.UTF_8);
	}

	/**
	 * 将yml文件转为Properties类
	 *
	 * @param path
	 * @return
	 */
	public static Properties getYml(String path) {
		ClassPathResource classPathResource = new ClassPathResource(path);
		return yml2Properties(classPathResource.getAbsolutePath());
	}

	/**
	 * 将yml文件转为x.x.x的Properties
	 *
	 * @param path
	 * @return
	 */
	private static Properties yml2Properties(String path) {
		final String DOT = ".";
		Properties prop = new Properties();
		try {
			YAMLFactory yamlFactory = new YAMLFactory();
			YAMLParser parser = yamlFactory.createParser(
					new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8));

			StringBuilder key = new StringBuilder();
			String value = null;
			JsonToken token = parser.nextToken();
			while (token != null) {
				if (JsonToken.START_OBJECT.equals(token)) {
					// do nothing
				} else if (JsonToken.FIELD_NAME.equals(token)) {
					if (key.length() > 0) {
						key.append(DOT);
					}
					key.append(parser.getCurrentName());

					token = parser.nextToken();
					if (JsonToken.START_OBJECT.equals(token)) {
						continue;
					}
					value = parser.getText();
					prop.setProperty(key.toString(), value);

					int dotOffset = key.lastIndexOf(DOT);
					if (dotOffset > 0) {
						key = new StringBuilder(key.substring(0, dotOffset));
					}
					value = null;
				} else if (JsonToken.END_OBJECT.equals(token)) {
					int dotOffset = key.lastIndexOf(DOT);
					if (dotOffset > 0) {
						key = new StringBuilder(key.substring(0, dotOffset));
					} else {
						key = new StringBuilder();
					}
				}
				token = parser.nextToken();
			}
			parser.close();
			return prop;
		} catch (Exception e) {
			logger.warn("Class path load yml occur error: {}", e.getMessage());
			throw new RuntimeException(e);
		}
	}
}
